<template>
  <el-drawer
    class="reset-drawer"
    :visible="visible"
    direction="rtl"
    :close-on-press-escape="false"
    :wrapperClosable="false"
    size="80%"
    :destroy-on-close="true"
    :show-close="false"
  >
    <div class="b g3 f16 tl" slot="title">
      <div class="ks-row-between ks-row-middle">
        <span>
          {{ title }}
        </span>
        <span class="el-icon-close g9 f26 poi" @click="handleClose"></span>
      </div>
    </div>
    <div class="container">
      <el-row :gutter="12" align="middle" type="flex">
        <el-col>脚本编码：{{ options.code }}</el-col>
        <el-col>脚本名称：{{ options.name }}</el-col>
        <el-col>脚本类型：{{ options.type }}</el-col>
        <el-col class="tr">
          <el-button
            style="margin-right: 15px"
            type="primary"
            @click="handleRun"
            >执行</el-button
          >
          <el-button type="primary" @click="handleSaveScript" plain
            >保存</el-button
          >
        </el-col>
      </el-row>
      <el-divider></el-divider>
      <el-row :gutter="12">
        <el-col :span="14">
          <el-card>
            <div id="java"></div>
          </el-card>
        </el-col>
        <el-col :span="10">
          <el-tabs v-model="activeTab" @tab-click="handleTabClick">
            <el-tab-pane label="调试信息" name="request">
              请求参数(JSON)
              <pre class="f10 g9">
              {
            "modelCode": "string", //模型编码，仅type未PROCESS时有效
            "type":"TRIGGER",//枚举值 TRIGGER和PROCESS
            "values": {}//流程模型的值仅type未PROCESS时有效
            }
          </pre
              >
              <el-divider></el-divider>
              <div class="mb40">
                <el-card>
                  <div id="json"></div>
                </el-card>
              </div>
              返回结构
              <el-divider></el-divider>
              <div class="mb40">
                <el-card style="min-height: 98px; overflow: auto">
                  <pre style="white-space: pre; overflow-x: auto">
  {{ returndata }}
                  </pre>
                </el-card>
              </div>
            </el-tab-pane>
            <el-tab-pane label="打印信息" name="console">
              <div v-show="activeTab === 'console'" class="mb40">
                <el-card class="mb10" v-for="(al, index) in logs" :key="index">
                  <div class="content">
                    <div class="text more" ref="more"></div>
                    <div class="text">
                      <div
                        :class="{ retract: al.status }"
                        :style="{ 'max-height': al.status ? textHeight : '' }"
                        ref="textContainer"
                      >
                        {{ al.log }}
                      </div>
                      <div class="btn">
                        <p v-if="al.status" @click="al.status = false">展开</p>
                        <p v-if="al.status == false" @click="al.status = true">
                          收起
                        </p>
                      </div>
                    </div>
                  </div>
                </el-card>
              </div>
            </el-tab-pane>
            <el-tab-pane label="报错信息" name="error">
              <div class="mb40">
                <el-card>
                  <pre>
              {{ errorMsg }}
          </pre
                  >
                </el-card>
              </div>
            </el-tab-pane>
          </el-tabs>
        </el-col>
      </el-row>
    </div>
  </el-drawer>
</template>
<script>
import { GROOVY_TEMPLATE } from "@/utils/const";
import {
  postHmscriptDebug,
  getHmscriptInfo,
  putHmscript,
} from "@/apis/paas/HmScriptController.js";
import jsonFormat from "json-format";
import * as monaco from "monaco-editor/esm/vs/editor/editor.api.js";
import MonacoEditorHint from "@/hint/monacoeditor";
MonacoEditorHint.init("java");
export default {
  name: "ScripSetCode",
  async mounted() {},
  data() {
    return {
      title: "脚本调试",
      options: {},
      visible: false,
      jsonEditor: null,
      javaEditor: null,
      errorMsg: "",
      returndata: "",
      logs: [],
      callback: null,
      activeTab: "request",
      textHeight: null,
    };
  },
  methods: {
    async showEdit(id, callback) {
      this.visible = true;
      this.options = await getHmscriptInfo({ id: id });
      this.options.content = decodeURIComponent(this.options.content);
      this.javaEditor = monaco.editor.create(document.getElementById("java"), {
        value: this.options.content || GROOVY_TEMPLATE,
        language: "java",
        minimap: {
          enabled: false,
        },
      });
      this.jsonEditor = monaco.editor.create(document.getElementById("json"), {
        value: `{
"modelCode":"string",
"type":"TRIGGER",
"values":{}
}`,
        language: "json",
        minimap: {
          enabled: false,
        },
      });
      await this.$nextTick();
      this.callback = callback;
    },
    async handleRun() {
      this.errorMsg = "";
      this.returndata = "";
      this.logs = [];
      const errorjson = monaco.editor.getModelMarkers();
      if (errorjson.length > 0) {
        this.$message.error("json语法错误" + errorjson[0]?.message);
        return;
      }
      try {
        const map = JSON.parse(this.jsonEditor.getValue());
        this.queryData = Object.assign(
          { code: encodeURIComponent(this.javaEditor.getValue()) },
          map
        );
        postHmscriptDebug(this.queryData, { nomsg: true })
          .then((res) => {
            this.activeTab = "request";
            try {
              if (!res) return;
              res = jsonFormat(JSON.parse(res), {
                type: "space",
                size: 4,
              });
            } catch {
            } finally {
              this.returndata = res;
              const logs = res.logs || [];
              logs.forEach((text, index) => {
                this.$set(
                  this.logs,
                  index,
                  Object.assign({}, { log: text }, { status: null })
                );
              });
            }
          })
          .catch((error) => {
            this.activeTab = "error";
            this.errorMsg = error.message;
          });
      } catch (error) {
        this.$message.error("json错误");
      }
    },
    handleSaveScript() {
      const params = {
        id: this.options.id,
        content: encodeURIComponent(this.javaEditor.getValue()),
      };
      putHmscript(params).then((res) => {
        this.$message.success("操作成功");
      });
    },
    handleClose() {
      this.visible = false;
      this.activeTab = "request";
      this.returndata = "";
      this.errorMsg = "";
      this.javaEditor.dispose();
      this.jsonEditor.dispose();
      this.jsonEditor = null;
      this.javaEditor = null;
    },
    // 计算文字 显示展开 收起
    calculateText() {
      // 获取一行文字的height 计算当前文字比较列表文字
      // let oneHeight = this.$refs.more.scrollHeight
      let twoHeight = 65;
      this.textHeight = `${twoHeight}px`;
      let txtDom = this.$refs.textContainer;
      for (let i = 0; i < txtDom.length; i++) {
        let curHeight = txtDom[i].offsetHeight;
        if (curHeight > twoHeight) {
          this.$set(
            this.logs,
            i,
            Object.assign({}, this.logs[i], { status: true })
          );
        } else {
          this.$set(
            this.logs,
            i,
            Object.assign({}, this.logs[i], { status: null })
          );
        }
      }
    },
    handleTabClick() {
      if (this.activeTab === "console") {
        if (this.logs.length) {
          // DOM 加载完执行
          this.$nextTick(() => {
            debugger;
            this.calculateText();
          });
        }
      }
    },
  },
};
</script>
<style lang="scss" scoped>
.reset-drawer ::v-deep .el-drawer__body {
  overflow: auto;
}
.container {
  padding-left: 20px;
  padding-right: 20px;
}

pre {
  white-space: pre-line;
  word-wrap: break-word;
}

#java {
  height: 600px;
}

#json {
  height: 200px;
}
.content {
  //display: flex;
  word-wrap: break-word;
}

.text {
  position: relative;
  font-size: 14px;
  line-height: 20px;
  //letter-spacing: 2px;
  color: #666666;
  width: calc(100% - 20px);
}

.retract {
  position: relative;
  overflow: hidden;
}

.retract:after {
  content: "...";
  position: absolute;
  bottom: 0;
  right: 2px;
  width: 25px;
  padding-left: 30px;
  background: linear-gradient(to right, transparent, #fff 45%);
}

.btn {
  position: absolute;
  right: 0;
  bottom: -30px;
  font-size: 14px;
  line-height: 19px;
  letter-spacing: 2px;
  color: #409eff;
  cursor: pointer;
}

.more {
  font-size: 14px;
  line-height: 20px;
  letter-spacing: 2px;
  color: #666666;
  visibility: hidden;
}
</style>
